package core.validate;

import java.util.regex.Pattern;

public class StringRule extends Rule<StringRule> {
    public StringRule(String key) {
        super(key);
        actions.add(holder -> {
            Object value = holder.getValue();
            boolean status = false;
            if(value instanceof String){
                status = true;
            }else if(value instanceof Number){
                value = String.valueOf(value);
                status = true;
            }else if(value instanceof Boolean){
                value = value.toString();
                status = true;
            }
            holder.setStatus(status)
                    .setValue(value)
                    .setMessage("数据类型错误");
        });
    }
    protected StringRule inst(){
        return this;
    }

    private String getValue(Holder holder){
        return (String) holder.getValue();
    }

    public StringRule contain(String chr, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(value.contains(chr)).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule startWith(String chr, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(value.startsWith(chr)).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule endWith(String chr, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(value.endsWith(chr)).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule notStartWith(String chr, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(!value.startsWith(chr)).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule notEndWith(String chr, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(!value.endsWith(chr)).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule length(int length, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(value.codePoints().count() == length)
                    .setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule max(int max, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(value.codePoints().count() <= max)
                    .setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule min(int min, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(value.codePoints().count() >= min)
                    .setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule between(int min, int max, String message){
        actions.add(holder -> {
            String value = getValue(holder);
            long length = value.codePoints().count();
            boolean status = false;
            if(min < max){
                status = length >= min && length <= max;
            }else{
                status = length<= min && length >= max;
            }
            holder.setStatus(status).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule lower(String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(Pattern.compile("^[a-z]+$")
                    .matcher(value.replaceAll("[^A-Za-z]", ""))
                    .matches()
            ).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule upper(String message){
        actions.add(holder -> {
            String value = getValue(holder);
            holder.setStatus(Pattern.compile("^[A-Z]+$")
                    .matcher(value.replaceAll("[^A-Za-z]", ""))
                    .matches()
            ).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule zip(){ return this; }

    public StringRule email(){ return this; }

    public StringRule mobile(){ return this; }

    public StringRule idCard(){ return this; }

    public StringRule macAddress(){ return this; }

    public StringRule url(String message){
        actions.add(holder -> {
            String value = holder.getValue();
            holder.setStatus(Pattern.compile("^(https?://)?[-_0-9a-zA-Z]+(\\.[-_0-9a-zA-Z]+)+(/[-_0-9a-zA-Z]+)+(\\.[a-zA-Z0-9])?(\\?.*)?$")
                    .matcher(value)
                    .matches()
            ).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule path(String message){
        actions.add(holder -> {
            String value = holder.getValue();
            holder.setStatus(Pattern.compile("^/?[-_0-9a-zA-Z]+(/[-_0-9a-zA-Z]+)+(\\.[0-9a-zA-Z]{1,5})?$")
                    .matcher(value)
                    .matches()).setMessage(getMessage(message));
        });
        return this;
    }

    public StringRule ip(){ return this; }

    public StringRule uuid(){ return this; }

    public StringRule json(){ return this; }

    public StringRule print(){ return this; }

    public StringRule alpha(){ return this; }

    public StringRule alphaNumeric(){ return this; }

    public StringRule alphaDash(){ return this; }

    public StringRule Ascii(){ return this; }

    public StringRule chs(){ return this; }

    public StringRule chsAlpha(){ return this; }

    public StringRule chsAlphaNumeric(){ return this; }

    public StringRule chsDash(){ return this; }
}
